package com.itheima.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.commo.PageResult;
import com.itheima.commo.R;
import com.itheima.dto.DishDto;
import com.itheima.entity.Category;
import com.itheima.entity.Dish;
import com.itheima.entity.DishFlavor;
import com.itheima.exception.BusinessException;
import com.itheima.mapper.DishMapper;
import com.itheima.service.CategoryService;
import com.itheima.service.DishFlavorService;
import com.itheima.service.DishService;
import com.itheima.service.SetmealDishService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜品业务层实现类
 * 注意：针对当前功能 菜品口味建立业务接口实现类，好处 如果业务比较复杂的时候，这个口味代码可以复用
 */

@Service
@Slf4j
@Transactional
public class DishServiceImpl implements DishService {
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;


    /**
     * 新增菜品
     *
     * @param dishDto
     */
    @Override
    public void saveWithFlavor(DishDto dishDto) {
        //1根据菜品名称查询菜品表
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StringUtils.isNotEmpty(dishDto.getName()), Dish::getName, dishDto.getName());
        Integer count = dishMapper.selectCount(lqw);
        //2如果存在相同菜品名则提示用户菜品已经存在
        if (count > 0) {
            throw new BusinessException("菜品[" + dishDto.getName() + "]已经存在了");
        }
        //3如果不存在相同菜品名称则插入菜品表
        dishMapper.insert(dishDto);

        //4.获取保存菜品表后主键id
        Long dishDtoId = dishDto.getId();

        //5.循环菜品口味记录 往菜品口味表中插入
        List<DishFlavor> flavors = dishDto.getFlavors();

        //集合非空判断
        if (!CollectionUtils.isEmpty(flavors)) {
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dishDtoId);//菜品口味表中设置菜品ID
                dishFlavorService.insert(flavor);
            }
        }
    }


    /**
     * 菜品分页查询
     *
     * @param page
     * @param pageSize
     * @param dish
     * @return
     */
    @Override
    public PageResult<DishDto> findPage(Long page, Long pageSize, String name) {
        // 2.1 new Page(page,pageSize)
        Page pp = new Page(page, pageSize);
        //2.1.1 添加name条件
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
//        lqw.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        lqw.eq(StringUtils.isNotEmpty(name), Dish::getName, name);//用户名
        lqw.eq(Dish::getIsDeleted, 0);
        lqw.orderByDesc(Dish::getCreateTime);
        //2.2 selectPage 进行分页;
        dishMapper.selectPage(pp, lqw);
        //得到菜品分页集合数据
        List<Dish> records = pp.getRecords();
        //将List<Dish>集合转换为List<DishDto>
        List<DishDto> dishDtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(records)) {
            dishDtoList = records.stream().map(
                    item -> {
                        DishDto dishDto = new DishDto();
                        BeanUtils.copyProperties(item, dishDto);
                        Category category = categoryService.findById(item.getCategoryId());
                        dishDto.setCategoryName(category.getName());
                        return dishDto;
                    }
            ).collect(Collectors.toList());
        }
        pp.setRecords(dishDtoList);//将转换后的 List<DishDto>设置Records属性上
        log.debug("员工分页总记录数{}，当前页面数据{}", pp.getTotal(), pp.getRecords());
        return new PageResult<>(pp.getTotal(), pp.getRecords());
    }


    /**
     * 根据菜品主键id查询菜品数据
     *
     * @param id
     * @return
     */
    @Override
    public DishDto findById(Long id) {
        DishDto dishDto = new DishDto();
        //1先根据菜品主键id查询菜品表
        Dish dish = dishMapper.selectById(id);
        //2再根据菜品id查询菜品口味表
        List<DishFlavor> dishFlavorList = dishFlavorService.findById(id);
        //3.将dish菜品数据copy到DishDto
        BeanUtils.copyProperties(dish, dishDto);
        //4.将菜品口味数据设置到dishDto中
        dishDto.setFlavors(dishFlavorList);
        return dishDto;
    }

    /**
     * 菜品修改
     *
     * @param dishDto
     */
    @Override
    public void update(DishDto dishDto) {
        //1根据菜品名称查询菜品表
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StringUtils.isNotEmpty(dishDto.getName()), Dish::getName, dishDto.getName());//菜品名称条件
        lqw.ne(Dish::getId, dishDto.getId());//排除自己 否则菜品名称没有修改的话 会提示已经存在
        Integer count = dishMapper.selectCount(lqw);
        //2如果存在相同菜品名则提示用户菜品已经存在
        if (count > 0) {
            throw new BusinessException("菜品[" + dishDto.getName() + "]已经存在了");
        }
        //3根据菜品id更新菜品表
        dishMapper.updateById(dishDto);
        //4先根据菜品id删除菜品口味表数据
        dishFlavorService.deleteById(dishDto.getId());
        //5将修改的口味数据再插入菜品口味表中
        List<DishFlavor> flavors = dishDto.getFlavors();
        if (!CollectionUtils.isEmpty(flavors)) {
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dishDto.getId());
                dishFlavorService.insert(flavor);
            }
        }
    }


    /**
     * 通过菜品分类id 查询菜品列表数据
     *
     * @param dish
     */
    @Override
    public List<DishDto> list(Dish dish) {
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        lqw.eq(Dish::getStatus, 1);
        lqw.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        //根据菜品分类id查询菜品数据
        List<Dish> dishList = dishMapper.selectList(lqw);
        //根据菜品分类id查询口味数据
        //将List<Dish>转为List<DishDto>集合
        List<DishDto> dishDtoList = dishList.stream().map(
                myDish -> {
                    //创建DishDto对象
                    DishDto dishDto = new DishDto();
                    //1将myDish 数据copy到dishDto
                    BeanUtils.copyProperties(myDish, dishDto);
                    //dishDto取数据到表中查询；菜品口味数据
                    //2根据菜品id到dishFlavor口味表中查询菜品口味数据
                    List<DishFlavor> dishFlavorList = dishFlavorService.findById(myDish.getId());
                    //3将dishFlavorList设置到dishDto中
                    dishDto.setFlavors(dishFlavorList);
                    return dishDto;
                }
        ).collect(Collectors.toList());
        return dishDtoList;
    }

    /**
     * 删除菜品表关联数据
     *
     * @param ids
     */
    @Override
    public void delete(List<Long> ids) {
        if (!CollectionUtils.isEmpty(ids)) {
            for (Long dishId : ids) {
                //1查询该批次套餐中是否存在售卖中的套餐
                LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
                //条件 套餐id + 状态==1 （1：启售 0：停售）
                lqw.eq(Dish::getId, dishId);
                lqw.eq(Dish::getStatus, 1);
                Dish dish = dishMapper.selectOne(lqw);
                //2如果在售, 不允许删除
                if (dish != null) {
                    throw new BusinessException("菜品[" + dish.getName() + "起售中，不能删除");
                }
            }
            //3如果停售 直接删除
            dishMapper.deleteBatchIds(ids);
            log.debug("**删除套餐数据成功了**");
            //4删除套餐关联的菜品数据
            setmealDishService.deleteByDishId(ids);
            log.debug("**删除套餐菜品数据成功了**");

        }
    }

    /**
     * p批量起售 停售
     *
     * @param status
     * @param ids
     */
    @Override
    public R<Dish> statusA(Integer status, List<Long> ids) {
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.in(Dish::getId, ids);
        Dish dish = new Dish();
        dish.setStatus(status);
        dishMapper.update(dish, lqw);
        return R.success("修改成功");
    }


}